import axios from "axios";
import io from "socket.io-client";

class Result {
  code: number;
  msg: string;
  data?: any;
  constructor(code: number, msg: string, data?: null) {
    this.code = code;
    this.msg = msg;
    this.data = data;
  }
}

export class WebScan {
  url: string;
  wsUrl: string;
  licence: string;
  clientId: string;
  isInit: boolean;
  isInUse: boolean;
  callback: any; // 根据实际需求确定回调函数的类型
  compressCallBack: any; // 根据实际需求确定回调函数的类型
  SocketClient: any;
  constructor(options: { url: string; wsUrl: string; licence: string }) {
    if (options.url == "" || options.url == null || options.url == undefined) {
      this.url = "http://localhost:18989/WebScan/";
    } else {
      this.url = options.url;
    }
    if (options.wsUrl == "" || options.wsUrl == null || options.wsUrl == undefined) {
      this.wsUrl = "http://localhost:28989";
    } else {
      this.wsUrl = options.wsUrl;
    }
    this.licence = options.licence;
    // 初始化其他属性
    this.clientId = "";
    this.isInit = false;
    this.isInUse = false;
    this.callback = null;
    this.compressCallBack = null;
    this.SocketClient = null;
  }
  /**
   * 初始化
   * @param {Object} pid 批次号
   * @param {Object} callback 回调函数
   */
  initSef(pid: Object, callback: Function): void {
    const that = this;
    axios
      .post(
        this.url + "/getVersionInfo",
        {
          licence: this.licence,
          pid: pid
        },
        {
          headers: { dataType: "json" }
        }
      )
      .then(res => {
        if (res.data.code == 200) {
          that.initSocketIo(res.data.data);
          that.clientId = res.data.data;
          that.isInit = true;
        }
        callback(res.data);
      });
  }
  /**
   * 追加授权
   * @param {Object} licence 授权码
   * @param {Object} callback 回调函数
   */
  saveLicence(licence: string, callback: Function): void {
    axios
      .post(this.url + "/saveLicence", {
        pid: this.clientId,
        licence: licence
      })
      .then(res => {
        callback(res.data);
      })
      .catch(error => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  }
  /**
   * 获取所有已授权限
   * @param
   */
  getPermission = (callback: Function) => {
    axios
      .get(this.url + "/custom/getPermission")
      .then((res: any) => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 初始化socketIO
   * @param {Object} id 批次ID
   */
  initSocketIo = (id: string) => {
    let transports = [];
    if (typeof WebSocket !== "undefined") {
      transports = ["websocket"];
    } else {
      transports = ["polling"];
    }
    this.SocketClient = io.connect(this.wsUrl + "?id=" + id, {
      transports: transports,
      rejectUnauthorized: false
    });
    let that = this;
    if (this.SocketClient != null && this.SocketClient != undefined) {
      this.SocketClient.on("error", (data: any) => {
        if (that.callback != null && that.callback != undefined) {
          let result = { code: 500, msg: data };
          that.callback(result);
        }
        that.isInUse = false;
      });
      this.SocketClient.on("success", function (data: any) {
        if (that.callback != null && that.callback != undefined) {
          let result = { code: 200, msg: data };
          that.callback(result);
        }
        that.isInUse = false;
      });
      // 连接成功
      this.SocketClient.on("connect", (data: any) => {
        if (that.callback != null && that.callback != undefined) {
          let result = { code: 200, msg: data };
          that.callback(result);
        }
        that.isInUse = false;
      });
      this.SocketClient.on("image", function (data: any) {
        if (that.callback != null && that.callback != undefined) {
          that.callback(data);
        }
      });
      this.SocketClient.on("result", function (data: any) {
        if (that.callback != null && that.callback != undefined) {
          that.callback(data);
        }
        that.isInUse = false;
      });
      this.SocketClient.on("connect_error", (err: any) => {
        console.log("初始化连接服务失败", err);
        return new Result(500, "初始化连接服务失败");
      });
      this.SocketClient.on("compress_process", function (data: any) {
        if (that.compressCallBack != null && that.compressCallBack != undefined) {
          that.compressCallBack(data);
        }
      });
    }
  };
  /**
   * 获取批次ID
   */
  getClientId = () => {
    return this.clientId;
  };
  /**
   * 设置批次ID,重新连接socketIO
   * @param {Object} pid
   */
  setClientId = (pid: string) => {
    if (this.clientId != pid) {
      this.SocketClient.disconnect();
      this.clientId = pid;
      this.initSocketIo(pid);
    }
  };
  /**
   * 获取所有图像
   * @param {Object} callback 回调函数
   */
  getAllImages = (callback: Function) => {
    axios
      .get(this.url + "/image/getImageByPid", {
        params: {
          pid: this.clientId
        }
      })
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 设置参数
   * @param {Object} params 参数字符串
   * @param {Object} callback 回调函数
   */
  setParams = (params: Object, callback: Function) => {
    const data = new FormData();
    data.append("pid", this.clientId);
    data.append("params", JSON.stringify(params));
    axios
      .post(this.url + "/setParams", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 获取系统设置参数
   * @param {Object} callback 回调函数
   */
  getParams = (callback: Function) => {
    axios
      .get(this.url + "/getParams", {
        params: {
          pid: this.clientId
        }
      })
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  getSystemValue = (code: string, callback: Function) => {
    axios
      .get(this.url + "/custom/getSystemValue", {
        params: {
          code: code
        }
      })
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 获取系统当前日志级别
   * @param {Object} callback
   */
  getLogLevel = (callback: Function) => {
    axios
      .get(this.url + "/log/getLevel")
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 加载模板
   * @param {Object} callback 回调函数
   */
  loadModels = (callback: Function) => {
    axios
      .get(this.url + "/model/modelList")
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  // 获取系统路径
  getFileExplore = (parentPath: string, isDirectory: boolean, callback: Function) => {
    axios
      .get(this.url + "/getFilePath", {
        params: {
          parentPath: parentPath,
          isDirectory: isDirectory
        }
      })
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 加载模板
   * @param id 模板ID
   * @param {Object} callback 回调函数
   */
  loadModelById = (id: string, callback: Function) => {
    axios
      .get(this.url + "/model/modelById", {
        params: {
          id: id
        }
      })
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 获取设备
   * @param {Object} callback 回调函数
   */
  getDevices = (callback: Function) => {
    axios
      .get(this.url + "/getDevices", {
        params: {
          pid: this.clientId
        }
      })
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 更改图像位置
   * @param {Object} oldIndex 原索引
   * @param {Object} newIndex 新索引
   * @param {Object} callback 回调函数
   */
  changeIndex = (oldIndex: string | Blob, newIndex: string | Blob, callback: Function) => {
    const data = new FormData();
    data.append("pid", this.clientId);
    data.append("oldIndex", oldIndex);
    data.append("newIndex", newIndex);
    axios
      .post(this.url + "/image/changeIndex", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 清空授权
   * @param {Object} callback
   */
  clearLicence = (callback: Function) => {
    axios
      .post(this.url + "/clearLicence")
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 设置日志级别
   * @param {Object} level DEBUG、INFO、WARN、ERROR
   * @param {Object} callback
   */
  setLogLevel = (level: string, callback: Function) => {
    const data = new FormData();
    data.append("level", level);
    axios
      .post(this.url + "/log/setLevel", data, {
        headers: {
          "Content-Type": "multipart/form-data"
        }
      })
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  // 下载日志
  downloadLogs = () => {
    window.location.href = this.url + "/log/downloadLogs";
  };
  /**
   * 合成OFD
   * @param {Object} isAuto 是否自动图像大小
   * @param {Object} isDouble 是否双层
   * @param {Object} callback 回调函数
   * @param {Object} compressCallback 双层合车较慢，支持进度回调，回调函数
   */
  majorOFD = (isAuto: boolean, isDouble: boolean, callback: Function, compressCallback: Function) => {
    const that = this;
    const formData = {
      isAuto: isAuto,
      isDouble: isDouble,
      pid: this.clientId
    };
    const data = new FormData();
    data.append("formDataString", JSON.stringify(formData));
    axios
      .post(this.url + "/majorOfd", data)
      .then(res => {
        callback(res.data);
        that.compressCallBack = compressCallback;
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 合成PDF
   * @param {Object} isDouble 是否双层
   * @param {Object} callback 回调函数
   */
  majorPDF = (isDouble: boolean, callback: Function) => {
    const formData = {
      pid: this.clientId,
      isDouble: isDouble
    };
    const data = new FormData();
    data.append("formDataString", JSON.stringify(formData));
    axios
      .post(this.url + "/majorPdf", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 合成ZIP
   * @param {Object} callback
   */
  majorZip = (callback: Function) => {
    const data = new FormData();
    data.append("pid", this.clientId);
    axios
      .post(this.url + "/downLoadZip", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 合成docx
   * @param {Object} isDouble 是否双层
   * @param {Object} callback 回调函数
   */
  majorDocx = (callback: Function, compressCallBack: Function) => {
    const that = this;
    that.compressCallBack = compressCallBack;
    const data = new FormData();
    data.append("pid", this.clientId);
    axios
      .post(this.url + "/majorDocx", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 骑订排序
   * @param {Object} mode 模式
   * @param {Object} callback 回调函数
   */
  sortImage = (mode: any, callback: Function) => {
    const data = new FormData();
    data.append("pid", this.clientId);
    data.append("mode", mode);
    axios
      .post(this.url + "/image/sortImage", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  // 模板管理删除
  deleteModel = (id: string, callback: Function) => {
    const data = new FormData();
    data.append("id", id);
    axios
      .post(this.url + "/model/deleteModel", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  // 扫描设定添加模板确认事件
  addModel = (name: string, value: string, callback: Function) => {
    const data = new FormData();
    data.append("name", name);
    data.append("value", value);
    axios
      .post(this.url + "/model/addModel", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  setSystemValue = (code: string, value: string, callback: Function) => {
    const data = new FormData();
    data.append("code", code);
    data.append("value", value);
    axios
      .post(this.url + "/custom/saveSystemValue", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 开始扫描
   * @param {Object} callback 回调函数
   * @param {Object} scanData 扫描参数
   */
  startScan = (callback: Function, scanData: any) => {
    if (this.isInUse == true) {
      return new Result(500, "设备使用中", null);
    }
    if (this.SocketClient != null && this.SocketClient != undefined) {
      this.SocketClient.emit("scan", JSON.stringify(scanData));
      this.callback = callback;
      this.isInUse = true;
      return new Result(200, "开启成功", null);
    } else {
      return new Result(500, "连接失败", null);
    }
  };
  /**
   * 合并图像
   * @param {Object} isHorizontal 水平|垂直
   * @param {Object} indexs 图像索引
   * @param {Object} callback 回调函数
   */
  merge = (isHorizontal: any, indexs: any, callback: Function) => {
    const data = new FormData();
    data.append("pid", this.clientId);
    data.append("isHorizontal", isHorizontal);
    for (let i = 0; i < indexs.length; i++) {
      data.append("indexs[]", indexs[i]);
    }
    axios
      .post(this.url + "/image/mergeHorizontal", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 上传图像
   * @param {Object} uploadParam 上传参数对象
   * @param {Object} callback 回调函数
   */
  uploadImage = (uploadParam: any, callback: Function) => {
    uploadParam.pid = this.clientId;
    const data = new FormData();
    data.append("formDataString", JSON.stringify(uploadParam));
    axios
      .post(this.url + "/uploadImage", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  // 公文抽取
  extractByImageName = (imageName: string, callback: Function) => {
    const data = new FormData();
    data.append("imageName", imageName);
    data.append("pid", this.clientId);
    axios
      .post(this.url + "/ocr/extractTextByImageName", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  // 批次抽取
  extractImageByPid = (callback: Function) => {
    const data = new FormData();
    data.append("pid", this.clientId);
    axios
      .post(this.url + "/ocr/extractImageByPid", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 根据索引删除图像
   * @param {Object} indexs 索引数组
   * @param {Object} callback 回调函数
   */
  deleteByIndexes = (indexs: any, callback: Function) => {
    const data = new FormData();
    data.append("pid", this.clientId);
    data.append("indexs[]", indexs);
    axios
      .post(this.url + "/image/deleteByIndexes", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 删除所有的图像
   * @param {Object} callback
   */
  deleteAllImage = (callback: Function) => {
    const data = new FormData();
    data.append("pid", this.clientId);
    axios
      .post(this.url + "/image/deleteAllImage", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  getTodayOfd = (callback: Function) => {
    axios
      .get(this.url + "/custom/getTodayOfd")
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 拆分图像
   * @param {Object} imageName 图像名称
   * @param {Object} isHorizontal 水平|垂直
   * @param {Object} x1 坐标起始点X轴
   * @param {Object} y1 坐标起始点Y轴
   * @param {Object} x2 坐标终止点X轴
   * @param {Object} y2 坐标终止点Y轴
   * @param {Object} callback 回调函数
   */
  split = (imageName: string, isHorizontal: any, x1: any, y1: any, x2: any, y2: any, callback: Function) => {
    const data = new FormData();
    data.append("pid", this.clientId);
    data.append("imageName", imageName);
    data.append("isHorizontal", isHorizontal);
    data.append("x1", parseInt(x1) as any);
    data.append("y1", parseInt(y1) as any);
    data.append("x2", parseInt(x2) as any);
    data.append("y2", parseInt(y2) as any);
    axios
      .post(this.url + "/image/split", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  // 保存图像
  saveImage = (imageName: string, base64: string, callback: Function) => {
    const data = new FormData();
    data.append("pid", this.clientId);
    data.append("imageName", imageName);
    data.append("image", base64);
    axios
      .post(this.url + "/image/saveImage", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
  /**
   * 区域识别
   * @param {Object} imageName 文件名称
   * @param {Object} left 左上角X轴坐标
   * @param {Object} top 左上角Y轴坐标
   * @param {Object} right 右上角X轴坐标
   * @param {Object} bottom 右上角Y轴坐标
   * @param {Object} callback
   */
  recognizeRegion = (imageName: string, left: any, top: any, right: any, bottom: any, callback: Function) => {
    const data = new FormData();
    data.append("pid", this.clientId);
    data.append("imageName", imageName);
    data.append("left", left);
    data.append("top", top);
    data.append("right", right);
    data.append("bottom", bottom);
    axios
      .post(this.url + "/image/saveImage", data)
      .then(res => {
        callback(res.data);
      })
      .catch(() => {
        const result = new Result(500, "网络错误", null);
        callback(result);
      });
  };
}
